package com.wfs.myapp.service.impl;

import com.wfs.myapp.common.ApiResult;
import com.wfs.myapp.entity.domain.bk.BkSearchTop;
import com.wfs.myapp.entity.dto.req.bk.SearchCollectionReqDto;
import com.wfs.myapp.entity.vo.OrderVo;
import com.wfs.myapp.entity.vo.SearchVo;
import com.wfs.myapp.enums.BookStatusEnum;
import com.wfs.myapp.enums.OrderStatusEnum;
import com.wfs.myapp.enums.SearchTypeEnum;
import com.wfs.myapp.enums.UserStatusEnum;
import com.wfs.myapp.repository.UserRepository;
import com.wfs.myapp.repository.bk.BookRepository;
import com.wfs.myapp.repository.bk.GroupRepository;
import com.wfs.myapp.repository.bk.OrderRepository;
import com.wfs.myapp.repository.bk.SearchTopRepository;
import com.wfs.myapp.service.BkSearchService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BkSearchServiceImpl implements BkSearchService {

    @Autowired
    private BookRepository bookRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private GroupRepository groupRepository;

    @Autowired
    private SearchTopRepository searchTopRepository;

    @Autowired
    private OrderRepository orderRepository;

    @Override
    public ApiResult<SearchVo> search(String name, Integer type) {
        SearchVo searchVo = new SearchVo();
        if (SearchTypeEnum.USER.getCode().equals(type)) {
            List<SearchVo.SearchItem> searchVoList = userRepository.findBySearchName(name);
            List<SearchVo.SearchItem> collect = searchVoList.stream().filter(searchItem -> searchItem.getType().equals(SearchTypeEnum.USER.getCode())).map(searchItem -> {
                searchItem.setStatusStr(UserStatusEnum.getMsg(searchItem.getStatus()));
                return searchItem;
            }).collect(Collectors.toList());
            searchVo.setBookList(collect);
        } else if (SearchTypeEnum.BOOK.getCode().equals(type)) {
            List<SearchVo.SearchItem> searchVoList = bookRepository.findBySearchName(name);
            List<SearchVo.SearchItem> collect = searchVoList.stream().filter(searchItem -> searchItem.getType().equals(SearchTypeEnum.BOOK.getCode())).map(searchItem -> {
                searchItem.setStatusStr(BookStatusEnum.getMsg(searchItem.getStatus()));
                return searchItem;
            }).collect(Collectors.toList());
            searchVo.setBookList(collect);
        } else if (SearchTypeEnum.GROUP.getCode().equals(type)) {
            List<SearchVo.SearchItem> searchVoList = groupRepository.findBySearchName(name);
            searchVo.setGroupList(searchVoList.stream().filter(searchItem -> searchItem.getType().equals(SearchTypeEnum.GROUP.getCode())).collect(Collectors.toList()));
        } else {
            List<SearchVo.SearchItem> searchVoList = bookRepository.findAllBySearchName(name);
            searchVo.setUserList(searchVoList.stream().filter(searchItem -> searchItem.getType().equals(SearchTypeEnum.USER.getCode())).map(searchItem -> {
                searchItem.setStatusStr(UserStatusEnum.getMsg(searchItem.getStatus()));
                return searchItem;
            }).collect(Collectors.toList()));
            searchVo.setBookList(searchVoList.stream().filter(searchItem -> searchItem.getType().equals(SearchTypeEnum.BOOK.getCode())).map(searchItem -> {
                searchItem.setStatusStr(BookStatusEnum.getMsg(searchItem.getStatus()));
                return searchItem;
            }).collect(Collectors.toList()));
            searchVo.setGroupList(searchVoList.stream().filter(searchItem -> searchItem.getType().equals(SearchTypeEnum.GROUP.getCode())).collect(Collectors.toList()));
        }
        return ApiResult.success(searchVo);
    }

    @Override
    public ApiResult<Void> searchCollection(SearchCollectionReqDto searchCollectionReqDto, Long userId) {
        BkSearchTop searchTop = searchTopRepository.findByTypeAndSearchId(searchCollectionReqDto.getType(), searchCollectionReqDto.getId());
        if (Objects.nonNull(searchTop)) {
            searchTop.setNumber(searchTop.getNumber()+1);
            searchTop.setUpdatedBy(String.valueOf(userId));
            searchTop.setUpdatedTime(LocalDateTime.now());
        } else {
            searchTop = new BkSearchTop();
            searchTop.setType(searchCollectionReqDto.getType());
            searchTop.setSearchId(searchCollectionReqDto.getId());
            searchTop.setNumber(1l);
            searchTop.setCreatedBy(String.valueOf(userId));
            searchTop.setUpdatedBy(String.valueOf(userId));
        }
        searchTopRepository.save(searchTop);
        return ApiResult.success();
    }

    @Override
    public ApiResult<List<SearchVo.SearchItem>> getTopList(Integer type, int page, int size) {
        List<SearchVo.SearchItem> list = new ArrayList<>();
        if (SearchTypeEnum.USER.getCode().equals(type)) {
            list = searchTopRepository.findUserTop(type, (page-1)*size, size);
        } else if (SearchTypeEnum.BOOK.getCode().equals(type)) {
            list = searchTopRepository.findBookTop(type, (page-1)*size, size);
            list.forEach(item -> item.setStatusStr(BookStatusEnum.getMsg(item.getStatus())));
        }
        return ApiResult.success(list);
    }

    @Override
    public ApiResult<List<OrderVo>> searchOrder(Long userId, Integer direction, String name) {
        List<OrderVo> orderVos = orderRepository.searchByName(userId, direction, "%"+name+"%");
        orderVos.forEach(orderVo -> orderVo.setStatusStr(OrderStatusEnum.getMsg(orderVo.getStatus())));
        return ApiResult.success(orderVos);
    }

}
